unit Formula;

interface

uses
  GlobalRecordsAndEnums, Classes;

type
  EOperator = (None, Add, Subtract, Multiply, Divide, Pwr);
  ETokenType = (Constant, Operator, BeginIdentifier, EndIdentifier, BeginOperation, EndOperation);
  EIdentifier = (Error, Base, EncrSkill, Skill1, Skill2, Datacore1, Datacore2, Decryptor, Meta);

  TToken = class
  end;

  TIdentifier = class(TToken)
    private
    public
      Value: EIdentifier;
      constructor Create(value: EIdentifier);
  end;

  TConstant = class(TToken)
    private
    public
      Value: Double;
      constructor Create(value: Double);
  end;

  TBeginOper = class(TToken)
  end;
  TEndOper = class(TToken)
  end;
  TOperator = class(TToken)
    public
      Operator: EOperator;
      constructor Create(op: EOperator);
  end;

  TOper = class(TToken)
    private
      tokens: TList;
      operators: TList;
      function GetTokenCount: Integer;
    public
      Parent: TOper;

      constructor Create(parent: TOper);
      destructor Destroy; reintroduce;

      procedure AddToken(token: TToken);
      procedure AddOperator(op: TOperator);
      function GetToken(index: Integer): TToken;
      function GetOperator(index: Integer): TOperator;

      property TokenCount: Integer read GetTokenCount;
  end;

implementation

uses SysUtils;

constructor TIdentifier.Create(value: EIdentifier);
begin
  self.Value := value;
end;

constructor TConstant.Create(value: Double);
begin
  self.Value := value;
end;

constructor TOperator.Create(op: EOperator);
begin
  Operator := op;
end;
                      
constructor TOper.Create(parent: TOper);
begin
  self.Parent := parent;
  tokens := TList.Create;
  operators := TList.Create;
end;

destructor TOper.Destroy;
var
  i: Integer;
begin
  for i := 0 to tokens.Count -1 do begin
    TToken(tokens[i]).Destroy;
  end;
  for i := 0 to operators.Count -1 do begin
    TOperator(operators[i]).Destroy;
  end;
  tokens.Destroy;
  operators.Destroy;
end;

function Toper.GetTokenCount: Integer;
begin
  result := tokens.Count;
end;

procedure TOper.AddToken(token: TToken);
begin
  tokens.Add(token);
end;

procedure TOper.AddOperator(op: TOperator);
begin
  operators.Add(op);
end;

function TOper.GetToken(index: Integer): TToken;
begin
  if (index >= tokens.count) then result := nil
  else result := tokens[index];
end;

function TOper.GetOperator(index: Integer): TOperator;
begin
  if (index >= operators.count) then result := nil
  else result := operators[index];
end;

end.

